package de.fhaugsburg.games.boardgames.scrabble;

import de.fhaugsburg.games.boardgames.GridPoint;
import de.fhaugsburg.games.boardgames.Player.PlayerType;
import de.fhaugsburg.games.boardgames.exceptions.GameException;
import de.fhaugsburg.games.boardgames.exceptions.IllegalMoveException;
import de.fhaugsburg.games.boardgames.scrabble.scrabbleboard.LetterPiece;
import de.fhaugsburg.games.boardgames.scrabble.scrabbleboard.ScrabbleBoard;

public interface IScrabbleEngine {

	public static final int MAX_PLAYERS = 4;
	public static final int MAX_PIECES = 7;


		
	public static enum State{
		INITIAL, DROPPING, COMMITED, GAMEOVER;
	}
	
	
	/**
	 * return number of players registered with the engine
	 * @return
	 */
	public abstract int getNumberOfPlayers();
	
	
	/**
	 * registers user interface to do repainting if needed
	 * @param guiMessage
	 */
	public abstract void registerGui(
			de.fhaugsburg.games.boardgames.scrabble.consoleui.IGuiMessage guiMessage);

	/**
	 * starts new game
	 * @param numPlayers
	 */
	public abstract void newGame();

	/**
	 * starts the game, if enough players available
	 * @throws GameException 
	 */
	public abstract void startGame() throws GameException;

	/**
	 * adds a player to the game and get him 7 pieces, if available
	 * a maximum number of 4 players can play Scrabble
	 * @param playerName
	 * @param cpuPlayer
	 * @throws GameException 
	 */
	public abstract int addPlayer(String playerName, PlayerType playerType)
			throws GameException;

	/**
	 * returns currently moving player
	 * @return
	 */
	public abstract ScrabblePlayer getActivePlayer();

	/**
	 * sets a letter at given coordinates
	 * @param letter
	 * @param row
	 * @param column
	 * @throws IllegalMoveException 
	 */
	public abstract void setLetter(LetterPiece letter, int row, int column)
			throws IllegalMoveException;

	
	/**
	 * sets a letter a given GripPoint
	 * @param letter
	 * @param gridPoint
	 * @throws IllegalMoveException
	 */
	public void setLetter(LetterPiece letter, GridPoint gridPoint) 
			throws IllegalMoveException;
	
	
	/**
	 * removes letter at position and adds it to the bar
	 * @param row
	 * @param column
	 * @throws IllegalMoveException 
	 */
	public abstract void removeLetter(int row, int column)
			throws IllegalMoveException;

	
	/**
	 * removes letter at given GridPoint
	 * @param gridPoint
	 * @throws IllegalMoveException
	 */
	public void removeLetter(GridPoint gridPoint) 
			throws IllegalMoveException;
	
	
	/**
	 * exchanges all pieces of the active player
	 * @throws IllegalMoveException
	 */
	public void exchangeAllPlayersPieces() throws IllegalMoveException;
	
	
	/**
	 * removes all letters from the current move and gives them back to active player
	 */
	public abstract void removeAllLetters();

	/**
	 * commit to fix the letters to the board
	 * all game-rules have to be checked here, before commit can be accepted
	 * @throws IllegalMoveException 
	 */
	public abstract void commitMove() throws IllegalMoveException;

	/**
	 * now do the commit and proceed to next player, score the points
	 */
	public abstract void commitAggreed();

	/**
	 * reject last commit and take back the pieces
	 */
	public abstract void commitRejected();

	/**
	 * pass, just continue next player
	 */
	public abstract void passMove();

	/**
	 * last words produced as a sting
	 * @return
	 */
	public abstract String getLastProdudedWordsAsString();

	/**
	 * get current state of game
	 * @return
	 */
	public abstract State getGameState();

	/**
	 * @return the gameMessage, only once
	 */
	public abstract String getGameMessage();

	/**
	 * returns whether gameMessage is available or not
	 * @return
	 */
	public abstract boolean gameMessageAvailable();

	
	/**
	 * returns reference to board used by the engine
	 * @return
	 */
	public abstract ScrabbleBoard getBoard();

	/**
	 * return the wordmanager of the engine (used by robots)
	 * @return
	 */
	public abstract WordManager getWordManager();
	
	/**
	 * undo last move
	 */
	public void undoLastMove();
}